// Decompiled by DJ v3.5.5.77 Copyright 2003 Atanas Neshkov  Date: 11/22/2007 7:40:26 PM
// Home Page : http://members.fortunecity.com/neshkov/dj.html  - Check often for new version!
// Decompiler options: packimports(3) 
// Source File Name:   MultipartIterator.java

package org.krcc.upload;

import java.io.*;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;

// Referenced classes of package org.apache.struts.upload:
//            MultipartElement, BufferedMultipartInputStream

public class MultipartIterator
{

    public MultipartIterator(HttpServletRequest request)
        throws ServletException
    {
        this(request, -1);
    }

    public MultipartIterator(HttpServletRequest request, int bufferSize)
        throws ServletException
    {
        this(request, bufferSize, -1L);
    }

    public MultipartIterator(HttpServletRequest request, int bufferSize, long maxSize)
        throws ServletException
    {
        this(request, bufferSize, maxSize, null);
    }

    public MultipartIterator(HttpServletRequest request, int bufferSize, long maxSize, String tempDir)
        throws ServletException
    {
        contentRead = false; 
        this.maxSize = -1L;
        totalLength = 0L;
        diskBufferSize = 20480;
        this.bufferSize = 4096;
        this.request = request;
        this.maxSize = maxSize;
        if(bufferSize > -1)
            this.bufferSize = bufferSize;
        if(tempDir != null)
            this.tempDir = tempDir;
        else
            tempDir = System.getProperty("java.io.tmpdir");
        parseRequest();
    }

    public MultipartElement getNextElement()
        throws ServletException, UnsupportedEncodingException
    {
        String disposition = readLine();
        if(disposition != null && disposition.startsWith("Content-Disposition"))
        {
            String name = parseDispositionName(disposition);
            String filename = parseDispositionFilename(disposition);
            String contentType = null;
            boolean isFile = filename != null;
            if(isFile)
            {
                filename = (new File(filename)).getName();
                int colonIndex = filename.indexOf(":");
                if(colonIndex == -1)
                    colonIndex = filename.indexOf("\\\\");
                int slashIndex = filename.lastIndexOf("\\");
                if(colonIndex > -1 && slashIndex > -1)
                    filename = filename.substring(slashIndex + 1, filename.length());
                contentType = readLine();
                contentType = parseContentType(contentType);
            }
            if(!isFile || contentType != null)
                readLine();
            MultipartElement element = null;
            if(isFile)
            {
                try
                {
                    File elementFile = createLocalFile(filename);
					System.out.println(elementFile.getAbsolutePath());
					isFile=true;
					System.out.println("Greater Than:\t"+isGreaterThan);
					System.out.println("Zero:\t"+isZero);
		
                    element = new MultipartElement(name, filename, contentType, elementFile,isGreaterThan,isZero);
                }
                catch(IOException ioe)
                {
                    ioe.printStackTrace(System.err);
                    throw new ServletException("IOException while reading file element: " + ioe.getMessage(), ioe);
                }
            } else
            {
                StringBuffer textData = new StringBuffer();
                for(String line = readLine(); line != null && !line.startsWith(boundary); line = readLine())
                    textData.append(line);

                if(textData.length() > 0 && textData.charAt(textData.length() - 1) == '\r')
                    textData.setLength(textData.length() - 1);
                element = new MultipartElement(name, textData.toString());  
            }
            return element;
        }
        if(inputStream.markSupported())
            try
            {
                inputStream.reset();
            }
            catch(IOException ioe)
            {
                throw new ServletException("IOException while resetting input stream: " + ioe.getMessage());
            }
        return null;
    }
//written by srikanth
    public MultipartElement getNextElement(boolean skipRead)
        throws ServletException, UnsupportedEncodingException
    {	isGreaterThan=false;
		isZero=false;
		isFile=false;
        String disposition = readLine();
        if(disposition != null && disposition.startsWith("Content-Disposition"))
        {
            String name = parseDispositionName(disposition);
            String filename = parseDispositionFilename(disposition);
            String contentType = null;
            boolean isFile = filename != null;
            if(isFile)
            {
                filename = (new File(filename)).getName();
                int colonIndex = filename.indexOf(":");
                if(colonIndex == -1)
                    colonIndex = filename.indexOf("\\\\");
                int slashIndex = filename.lastIndexOf("\\");
                if(colonIndex > -1 && slashIndex > -1)
                    filename = filename.substring(slashIndex + 1, filename.length());
                contentType = readLine();
                contentType = parseContentType(contentType);
            }
            if(!isFile || contentType != null)
                readLine();
            MultipartElement element = null;
            if(isFile)
            {
                try
                {
                    File elementFile = createLocalFile(filename,skipRead);
					//System.out.println(elementFile.getAbsolutePath());
					isFile=true;
					System.out.println("Is File:\t"+isFile);
					System.out.println("Greater Than:\t"+isGreaterThan);
					System.out.println("Zero:\t"+isZero);
					if(readRequest==true)
						return null;

					System.out.println("Is File:\t"+isFile);
					System.out.println("Greater Than:\t"+isGreaterThan);
					System.out.println("Zero:\t"+isZero);
		
                    element = new MultipartElement(name, filename, contentType, elementFile,isGreaterThan,isZero);
                }
                catch(IOException ioe)
                {
                    ioe.printStackTrace(System.err);
                    throw new ServletException("IOException while reading file element: " + ioe.getMessage(), ioe);
                }
            } else
            {
                StringBuffer textData = new StringBuffer();
                for(String line = readLine(); line != null && !line.startsWith(boundary); line = readLine())
                    textData.append(line);

                if(textData.length() > 0 && textData.charAt(textData.length() - 1) == '\r')
                    textData.setLength(textData.length() - 1);
                element = new MultipartElement(name, textData.toString());  
            }
            return element;
        }
        if(inputStream.markSupported())
            try
            {
                inputStream.reset();
            }
            catch(IOException ioe)
            {
                throw new ServletException("IOException while resetting input stream: " + ioe.getMessage());
            }
        return null;
    }

	public void setBufferSize(int bufferSize)
    {
        this.bufferSize = bufferSize;
    }

    public int getBufferSize()
    {
        return bufferSize;
    }

    public void setMaxSize(long maxSize)
    {
        this.maxSize = maxSize;
    }

    public long getMaxSize()
    {
        return maxSize;
    }

    protected void parseRequest()
        throws ServletException
    {

		contentLength = request.getContentLength();
        boundary = parseBoundary(request.getContentType());
		System.out.println("contentLength"+contentLength);
		System.out.println("boundary"+boundary);
        boundaryBytes = boundary.getBytes();
		System.out.println("boundary bytes"+boundaryBytes);
        try
        {
            inputStream = new BufferedMultipartInputStream(request.getInputStream(), bufferSize, contentLength, contentLength+1);
            if(inputStream.markSupported())
                inputStream.mark(contentLength + 1);
        }
        catch(IOException ioe)
        {
            throw new ServletException("Problem while reading request: " + ioe.getMessage(), ioe);
        }
        if(boundary == null || boundary.length() < 1)
            boundary = parseBoundary(request.getHeader("Content-type"));
        if(boundary == null || boundary.length() < 1)
            throw new ServletException("MultipartIterator: cannot retrieve boundary for multipart request");
        try
        {
            String firstLine = readLine();
            if(firstLine == null)
                throw new ServletException("MultipartIterator: no multipart request data sent");
            if(!firstLine.startsWith(boundary))
                throw new ServletException("MultipartIterator: invalid multipart request data, doesn't start with boundary");
        }
        catch(UnsupportedEncodingException unsupportedencodingexception)
        {
            throw new ServletException("MultipartIterator: encoding \"ISO-8859-1\" not supported");
        }
    }

    public static String parseBoundary(String contentType)
    {
        if(contentType.lastIndexOf("boundary=") != -1)
        {
            String _boundary = "--" + contentType.substring(contentType.lastIndexOf("boundary=") + 9);
            if(_boundary.endsWith("\n"))
                return _boundary.substring(0, _boundary.length() - 1);
            else
                return _boundary;
        } else
        {
            return null;
        }
    }

    public static String parseContentType(String contentTypeString)
    {
        int nameIndex = contentTypeString.indexOf("Content-Type: ");
        if(nameIndex == -1)
            nameIndex = contentTypeString.indexOf("\n");
        if(nameIndex != -1)
        {
            int endLineIndex = contentTypeString.indexOf("\n");
            if(endLineIndex == -1)
                endLineIndex = contentTypeString.length() - 1;
            return contentTypeString.substring(nameIndex + 14, endLineIndex);
        } else
        {
            return null;
        }
    }

    public static String parseDispositionName(String dispositionString)
    {
        return parseForAttribute("name", dispositionString);
    }

    public static String parseDispositionFilename(String dispositionString)
    {
        return parseForAttribute("filename", dispositionString);
    }

    public static String parseForAttribute(String attribute, String parseString)
    {
        int nameIndex = parseString.indexOf(attribute + "=\"");
        if(nameIndex != -1)
        {
            int endQuoteIndex = parseString.indexOf("\"", nameIndex + attribute.length() + 3);
            if(endQuoteIndex != -1)
                return parseString.substring(nameIndex + attribute.length() + 2, endQuoteIndex);
            else
                return "";
        } else
        {
            return null;
        }
    }

    protected String readLine()
        throws ServletException, UnsupportedEncodingException
    {
        if(totalLength >= (long)contentLength)
            return null;
        byte bufferByte[];
        int bytesRead;
        try
        {
            bufferByte = inputStream.readLine();
            if(bufferByte == null)
                return null;
            bytesRead = bufferByte.length;
        }
        catch(IOException ioe)
        {
            throw new ServletException("IOException while reading multipart request: " + ioe.getMessage());
        }
        if(bytesRead == -1)
        {
            return null;
        } else
        {
            totalLength += bytesRead;
            return new String(bufferByte, 0, bytesRead, "ISO-8859-1");
        }
    }

    protected File createLocalFile(String fileName)
        throws IOException
    {
		java.util.Date date=new java.util.Date();
		java.text.SimpleDateFormat sdf=new java.text.SimpleDateFormat("yyyy-MM-dd");
		java.util.StringTokenizer st=new java.util.StringTokenizer(sdf.format(date),"-");
		StringBuffer folderBuffer=new StringBuffer(tempDir);
		folderBuffer.append("/");
		String folder=null;
		while(st.hasMoreTokens()) {
			folderBuffer.append(st.nextToken());
			folder=new String(folderBuffer);
			File f=new File(folder);
			f.mkdir();
			folderBuffer.append("/");
		} 
//code is to write here
//		File tempFile = File.createTempFile("strts", null, new File(tempDir));
		StringBuffer sb=new StringBuffer(fileName);
		StringBuffer consFile=new StringBuffer();
		byte b=64;
		char ch;
		for(int i=0;i<sb.length();i++) {
		 ch=sb.charAt(i);
		 b=(byte)ch;
		 if((b>=48 && b<=57) || (b>=65 && b<=90) || (b>=97 && b<=122) || b==95 || b==46)
			consFile.append((char)b);
		}
		File tempFile = File.createTempFile("KRCC",consFile.toString(), new File(folder));
        BufferedOutputStream fos = new BufferedOutputStream(new FileOutputStream(tempFile), diskBufferSize);
        byte lineBuffer[] = inputStream.readLine();
        if(lineBuffer == null)
            throw new IOException("Premature end of stream while reading multipart request");
        int bytesRead = lineBuffer.length;
        boolean cutCarriage = false;
        boolean cutNewline = false;
		long totalBytes=0;
        try
        {
            for(; bytesRead != -1 && !equals(lineBuffer, 0, boundaryBytes.length, boundaryBytes); bytesRead = lineBuffer.length)
            {
			totalBytes+=lineBuffer.length;
		//	for(int i=0;i<lineBuffer.length-1;i++)
			//	System.out.print((char)lineBuffer[i]);
//			   else {
                if(cutCarriage && totalBytes<=maxSize)
                    fos.write(13);
                if(cutNewline && totalBytes<=maxSize)
                    fos.write(10);
                cutCarriage = false;
                if(bytesRead > 0 && lineBuffer[bytesRead - 1] == 13)
                {
                    bytesRead--;
                    cutCarriage = true;
                }
                cutNewline = true; 
			   if(totalBytes<=maxSize) {
				fos.write(lineBuffer, 0, bytesRead);
			   }           
				lineBuffer = inputStream.readLine();
                if(lineBuffer == null)
                    throw new IOException("Premature end of stream while reading multipart request");
            // }
			}
			   if(totalBytes==1) {  //1 is minimum
				isZero=true;
	        //    fos.close();
		    //    tempFile.delete();
			//	break;
			   }
			   if(totalBytes>maxSize) {  
				isGreaterThan=true;
	            fos.close();
		        tempFile.delete();
			//	break;
			   }

        }
        catch(IOException ioe)
        {
            fos.close();
            tempFile.delete();
            throw ioe;
        }
        fos.flush();
        fos.close();
        return tempFile;
    }
//written by srikanth it skips reading when file length is > max. lenght
    protected File createLocalFile(String fileName,boolean skipRead)
        throws IOException
    {
	//	System.out.println("----createLocalFile(String fileName,boolean skipRead)---"+skipRead);
	 	java.util.Date date=new java.util.Date();
		java.text.SimpleDateFormat sdf=new java.text.SimpleDateFormat("yyyy-MM-dd");
		java.util.StringTokenizer st=new java.util.StringTokenizer(sdf.format(date),"-");
		StringBuffer folderBuffer=new StringBuffer(tempDir);
		folderBuffer.append("/");
		String folder=null;
		while(st.hasMoreTokens()) {
			folderBuffer.append(st.nextToken());
			folder=new String(folderBuffer);
			File f=new File(folder);
			f.mkdir();
			folderBuffer.append("/");
		} 
//code is to write here
//		File tempFile = File.createTempFile("strts", null, new File(tempDir));
	System.out.println("fileName----------->"+fileName);
	    if(fileName.equals(""))
			return null;
		StringBuffer sb=new StringBuffer(fileName);
		StringBuffer consFile=new StringBuffer();
		byte b=64;
		char ch;
		for(int i=0;i<sb.length();i++) {
		 ch=sb.charAt(i);
		 b=(byte)ch;
		 if((b>=48 && b<=57) || (b>=65 && b<=90) || (b>=97 && b<=122) || b==95 || b==46)
			consFile.append((char)b);
		}
		File tempFile = File.createTempFile("KRCC",consFile.toString(), new File(folder));
//		System.out.println("--------->\t:"+tempFile.getName());
        BufferedOutputStream fos = new BufferedOutputStream(new FileOutputStream(tempFile), diskBufferSize);
        byte lineBuffer[] = inputStream.readLine();
        if(lineBuffer == null)
            throw new IOException("Premature end of stream while reading multipart request");
        int bytesRead = lineBuffer.length;
//		System.out.println("============"+bytesRead+" bytes");
        boolean cutCarriage = false;
        boolean cutNewline = false;
		long totalBytes=0;
        try
        {
//		System.out.println("----before for loop---");
            for(; readRequest==false && bytesRead != -1 && !equals(lineBuffer, 0, boundaryBytes.length, boundaryBytes); bytesRead = lineBuffer.length)
            {
//				System.out.println("----in for loop---"+totalBytes);
//				System.out.println("----Max Size---"+maxSize);
//				System.out.println("----readRequest---"+readRequest);
//				System.out.println("----skipRead---"+skipRead);
//				System.in.read();
//				System.in.read();
			totalBytes+=lineBuffer.length;
		//	for(int i=0;i<lineBuffer.length-1;i++)
			//	System.out.print((char)lineBuffer[i]);
//			   else {
                if(cutCarriage && totalBytes<=maxSize)
                    fos.write(13);
                if(cutNewline && totalBytes<=maxSize)
                    fos.write(10);
                cutCarriage = false;
                if(bytesRead > 0 && lineBuffer[bytesRead - 1] == 13)
                {
                    bytesRead--;
                    cutCarriage = true;
                }
                cutNewline = true; 
			   if(totalBytes<=maxSize) {
				fos.write(lineBuffer, 0, bytesRead);
			   }           
				lineBuffer = inputStream.readLine();
                if(lineBuffer == null)
                    throw new IOException("Premature end of stream while reading multipart request");
            // }
			   if(totalBytes==1) {  //1 is minimum
				isZero=true;
	        //    fos.close();
		    //    tempFile.delete();
			//	break;
			   }
			   if(totalBytes>maxSize) {  
				isGreaterThan=true;
	            fos.close();
		        tempFile.delete();
			//	break;
			   }
			if(totalBytes>maxSize && skipRead==true) {
				setReadRequest(true);
				readRequest=true;
			}
			}

        }
        catch(IOException ioe)
        {
            fos.close();
            tempFile.delete();
            throw ioe;
        }
        fos.flush();
        fos.close();
        return tempFile;
    }

	public static boolean equals(byte comp[], int offset, int length, byte source[])
    {
        if(length != source.length || comp.length - offset < length)
            return false;
        for(int i = 0; i < length; i++)
            if(comp[offset + i] != source[i])
                return false;

        return true;
    }
	public void setReadRequest(boolean readRequest) {
		this.readRequest=readRequest;
	}
	public boolean getReadRequest() {
		return readRequest;
	}
	//Srikanth written code
	public boolean isFile() {
		return isFile;
	}
	public boolean isGreaterThan() {
		return isGreaterThan;  
	}
	public boolean isZero() {
		return isZero;
	}

	public static int MAX_LINE_SIZE = 4096;
    protected HttpServletRequest request;
    protected BufferedMultipartInputStream inputStream;
    protected String boundary;
    protected byte boundaryBytes[];
    protected boolean contentRead;
    protected long maxSize;
    protected long totalLength;
    protected int contentLength;
    protected int diskBufferSize;
    protected int bufferSize;
    protected String tempDir;
	protected boolean isGreaterThan=false;
	protected boolean isZero=false;  
	protected boolean readRequest=false;  
	protected boolean isFile=false;  
}